package panda.android.notebook.view;

import java.util.ArrayList;
import java.util.List;

import panda.android.notebook.Utils.AppConfig;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.DecelerateInterpolator;
import android.widget.Scroller;

public class ImageEditView extends View {

	private Context mContext;
	private Paint mPaint;
	private List<WordModel> bitmapMDs = new ArrayList<WordModel>();

	public void setBitmapMDs(List<WordModel> bitmapMDs) {
		this.bitmapMDs = bitmapMDs;
		invalidate();
	}

	public List<WordModel> getBitmapMDs() {
		return bitmapMDs;
	}

	int viewHeight;
	int viewWidth;
	private static final int SPACE = 5;
	private Paint textPaint;
	private Paint signPaint;
	Cursor cursor;
	private Scroller mScroller;
	private int mTouchSlop;
	private int mMinimumVelocity;
	private int mMaximumVelocity;

	private float mLastMotionY;
	private boolean mIsBeingDragged;
	private VelocityTracker mVelocityTracker;
	private int mActivePointerId = INVALID_POINTER;

	private static final int INVALID_POINTER = -1;

	public ImageEditView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
		mContext = context;
		initView();
	}

	public ImageEditView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		mContext = context;
		initView();
	}

	public ImageEditView(Activity context) {
		super(context);
		// TODO Auto-generated constructor stub
		mContext = context;
		initView();
	}

	private void initView() {
		mScroller = new Scroller(mContext, new DecelerateInterpolator(0.5f));
		final ViewConfiguration configuration = ViewConfiguration.get(mContext);
		mTouchSlop = configuration.getScaledTouchSlop();
		mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
		mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();

		cursor = new Cursor();
		cursor.setPoint(LastX, LastY);

		mPaint = new Paint();
		mPaint.setColor(Color.GRAY);
		mPaint.setAntiAlias(true);

		textPaint = new Paint();
		textPaint.setAntiAlias(true);
		textPaint.setStyle(Paint.Style.STROKE);
		textPaint.setStrokeJoin(Paint.Join.ROUND);// 设置外边缘
		textPaint.setStrokeCap(Paint.Cap.SQUARE);// 形状
		textPaint.setColor(Color.RED);
		textPaint.setStrokeWidth(4);// 画笔宽度

		signPaint = new Paint();
		signPaint.setColor(Color.RED);
		signPaint.setAntiAlias(true);
		signPaint.setTextSize(50 * (AppConfig.ROWHEIGHT / 100.0f));

	}

	private int LastX = 10;
	private int LastY = 0;

	/**
	 * 添加一个标点
	 * */
	public void addSign(String sign) {

		Bitmap bitmap = Bitmap.createBitmap(getFontWidth(signPaint, sign),
				(int) AppConfig.ROWHEIGHT, Config.ARGB_8888);
		Canvas canvas = new Canvas(bitmap);

		canvas.drawText(sign, 0, getFontHeight(signPaint), signPaint);

		// 预测 这个字会不会超出屏幕 如果超出 则换行
		if (LastX + bitmap.getWidth() + SPACE >= viewWidth) {
			LastX = 10;
			LastY += AppConfig.ROWHEIGHT;
		}
		WordModel bitmapMD = new WordModel(mContext, WordModel.WORD);
		bitmapMD.setBitmap(bitmap);
		bitmapMD.setX(LastX);
		bitmapMD.setY(LastY);
		bitmapMD.setWidth(bitmap.getWidth());
		bitmapMD.setHeight(bitmap.getHeight());
		bitmapMDs.add(bitmapMD);
		LastX += bitmap.getWidth();

		cursor.setPoint(LastX, LastY);
		invalidate();
		disposeScroll();
	}

	/**
	 * 添加一个文字
	 * */
	public void addText(Word word) {

		float width = 0, height = 0;
		width = AppConfig.ROWHEIGHT;
		height = AppConfig.ROWHEIGHT;
		if (width <= 1 || height <= 1)
			return;
		Bitmap bitmap = Bitmap.createBitmap((int) width, (int) height,
				Config.ARGB_8888);
		Canvas canvas = new Canvas(bitmap);
		List<Path> paths = word.getPath();
		for (int i = 0; i < paths.size(); i++) {
			Path path = paths.get(i);
			canvas.drawPath(path, textPaint);
		}

		// 预测 这个字会不会超出屏幕 如果超出 则换行
		if (LastX + bitmap.getWidth() + SPACE >= viewWidth) {
			LastX = 10;
			LastY += AppConfig.ROWHEIGHT;
		}
		WordModel bitmapMD = new WordModel(mContext, WordModel.WORD);
		bitmapMD.setBitmap(bitmap);
		bitmapMD.setX(LastX);
		bitmapMD.setY(LastY);
		bitmapMD.setWidth(bitmap.getWidth());
		bitmapMD.setHeight(bitmap.getHeight());
		bitmapMDs.add(bitmapMD);
		LastX += bitmap.getWidth();

		cursor.setPoint(LastX, LastY);
		invalidate();
		disposeScroll();
	}

	public void addResource(WordModel model) {

		// 预测 这个字会不会超出屏幕 如果超出 则换行
		if (LastX + model.getWidth() + SPACE >= viewWidth) {
			LastX = 10;
			LastY += AppConfig.ROWHEIGHT;
		}
		model.setX((int) LastX);
		model.setY((int) LastY);
		bitmapMDs.add(model);

		LastX += model.getWidth() + AppConfig.SPACE;
		cursor.setPoint(LastX, LastY);
		invalidate();
		disposeScroll();
	}

	/**
	 * 换行
	 * */
	public void Enter() {
		LastX = 10;
		LastY += AppConfig.ROWHEIGHT;
		WordModel bitmapMD = new WordModel(mContext, WordModel.WORD);
		bitmapMD.setBitmap(null);
		bitmapMD.setX(LastX);
		bitmapMD.setY(LastY);
		bitmapMD.setWidth(0);
		bitmapMD.setHeight(LastY);
		bitmapMDs.add(bitmapMD);
		cursor.setPoint(LastX, LastY);
		invalidate();
		disposeScroll();
	}

	/**
	 * 空格
	 * */
	public void Space() {
		Word word = new Word();
		word.setSTATE(Word.SPACE);
		addText(word);
	}

	/**
	 * 删除一个文字
	 * */
	public void delText() {
		if (bitmapMDs.size() == 0)
			return;

		bitmapMDs.remove(bitmapMDs.size() - 1);
		if (bitmapMDs.size() == 0) {
			LastX = 10;
			LastY = 0;
		} else {
			WordModel bitmapMD = bitmapMDs.get(bitmapMDs.size() - 1);
			LastX = bitmapMD.getX();
			LastY = bitmapMD.getY();

			LastX += bitmapMD.getWidth() + SPACE;
			if (LastX >= viewWidth) {
				LastX = 10;
				LastY += AppConfig.ROWHEIGHT;
			}
		}

		cursor.setPoint(LastX, LastY);
		invalidate();
		disposeScroll();
	}

	private void disposeScroll() {
		// TODO Auto-generated method stub
		if (LastY > getHeight())
			scrollTo(0, (int) (LastY - getHeight() + AppConfig.ROWHEIGHT));
		if (LastY < getHeight()) {
			scrollTo(0, 0);
		}
	}

	/**
	 * 设置文字粗细
	 * */
	public void setWordWidth(float size) {
		textPaint.setStrokeWidth(size);
	}

	/**
	 * 设置文字颜色
	 * */
	public void setTextColor(int color) {
		textPaint.setColor(color);
		signPaint.setColor(color);
	}

	public void clean() {
		// TODO Auto-generated method stub
		bitmapMDs.clear();

		LastX = 10;
		LastY = 0;
		cursor.setPoint(LastX, LastY);
		invalidate();
		scrollTo(0, 0);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);

		canvas.drawColor(0xE0E0E0);

		float rowHeight = AppConfig.ROWHEIGHT;

		viewWidth = getWidth();
		viewHeight = getLineCount() * getLineHeight() <= getHeight() ? getHeight()
				: getLineCount() * getLineHeight();

		// 绘制细线
		int count = viewHeight / (int) rowHeight;
		for (int i = 0; i < count; i++) {
			canvas.drawLine(5, rowHeight * i + rowHeight, viewWidth - 5,
					rowHeight * i + rowHeight, mPaint);
		}

		// 绘制文字
		for (int i = 0; i < bitmapMDs.size(); i++) {
			WordModel bitmapMD = bitmapMDs.get(i);
			bitmapMD.Draw(canvas, mPaint);
			// if(bitmapMD.getType()==BitmapMD.LUYIN||bitmapMD.getType()==BitmapMD.PIC)
			// setResListen(((Tag_Resources)bitmapMD));
			if (i == bitmapMDs.size() - 1) {
				LastX = bitmapMD.x + bitmapMD.width;
				LastY = bitmapMD.y;
				cursor.setPoint(LastX, LastY);

			}
		}

		cursor.draw(canvas);
	}

	/**
	 * 获取字符串宽
	 * 
	 * @param str
	 * @return
	 */
	private int getFontWidth(Paint paint, String str) {
		return (int) paint.measureText(str);
	}

	/*
	 * 获取字体高度
	 */
	private int getFontHeight(Paint paint) {
		FontMetrics fm = paint.getFontMetrics();
		return (int) (fm.descent - fm.top);
	}

	/**
	 * 此方法为最后机会来修改mScrollX,mScrollY. 这方法后将根据mScrollX,mScrollY来偏移Canvas已实现内容滚动
	 */
	@Override
	public void computeScroll() {
		super.computeScroll();

		final Scroller scroller = mScroller;
		if (scroller.computeScrollOffset()) { // 正在滚动，让view滚动到当前位置
			int scrollY = scroller.getCurrY();
			final int maxY = (getLineCount() * getLineHeight()
					+ getPaddingTop() + getPaddingBottom())
					- getHeight();
			boolean toEdge = scrollY < 0 || scrollY > maxY;
			if (scrollY < 0)
				scrollY = 0;
			else if (scrollY > maxY)
				scrollY = maxY;

			/*
			 * 下面等同于： mScrollY = scrollY; awakenScrollBars(); //显示滚动条，必须在xml中配置。
			 * postInvalidate();
			 */
			scrollTo(0, scrollY);
			if (toEdge) // 移到两端，由于位置没有发生变化，导致滚动条不显示
				awakenScrollBars();
		}
	}

	public void fling(int velocityY) {
		final int maxY = (getLineCount() * getLineHeight() + getPaddingTop() + getPaddingBottom())
				- getHeight();

		mScroller.fling(getScrollX(), getScrollY(), 0, velocityY, 0, 0, 0,
				Math.max(0, maxY));

		// 刷新，让父控件调用computeScroll()
		invalidate();
	}

	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		super.onTouchEvent(ev);
		/*
		 * 事件处理方式：先自己处理后交给父类处理。 PS:方式不同，可能导致效果不同。请根据需求自行修改。
		 */
		boolean handled = false;
		final int contentHeight = getLineCount() * getLineHeight();
		if (contentHeight > getHeight()) {
			handled = processScroll(ev);
		}

		for (WordModel bitmapMD : bitmapMDs) {
			if (bitmapMD.getType() == WordModel.LUYIN
					|| bitmapMD.getType() == WordModel.PIC|| bitmapMD.getType() == WordModel.VIDEO)
				bitmapMD.onTouchEvent(ev, this);
		}
		return true;
	}

	private int getLineHeight() {
		// TODO Auto-generated method stub
		return (int) AppConfig.ROWHEIGHT;
	}

	private int getLineCount() {
		// TODO Auto-generated method stub
		return (int) (LastY / AppConfig.ROWHEIGHT + 1);
	}

	private boolean processScroll(MotionEvent ev) {
		boolean handled = false;
		if (mVelocityTracker == null) {
			mVelocityTracker = VelocityTracker.obtain();
		}
		mVelocityTracker.addMovement(ev); // 帮助类，用来在fling时计算移动初速度

		final int action = ev.getAction();

		switch (action) {
		case MotionEvent.ACTION_DOWN:
			if (!mScroller.isFinished()) {
				mScroller.forceFinished(true);
			}

			mLastMotionY = ev.getY();
			mActivePointerId = ev.getPointerId(0);
			mIsBeingDragged = true;
			handled = true;
			break;

		case MotionEvent.ACTION_MOVE:
			int pointerId = mActivePointerId;
			if (mIsBeingDragged && INVALID_POINTER != pointerId) {
				final int pointerIndex = ev.findPointerIndex(pointerId);
				final float y = ev.getY(pointerIndex);
				int deltaY = (int) (mLastMotionY - y);

				if (Math.abs(deltaY) > mTouchSlop) {
					mLastMotionY = y;

					mScroller.startScroll(getScrollX(), getScrollY(), 0,
							deltaY, 0);
					invalidate();
					handled = true;
				}
			}
			break;

		case MotionEvent.ACTION_UP:
			pointerId = mActivePointerId;
			if (mIsBeingDragged && INVALID_POINTER != pointerId) {
				final VelocityTracker velocityTracker = mVelocityTracker;
				velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
				int initialVelocity = (int) velocityTracker
						.getYVelocity(pointerId);

				if (Math.abs(initialVelocity) > mMinimumVelocity) {
					fling(-initialVelocity);
				}

				mActivePointerId = INVALID_POINTER;
				mIsBeingDragged = false;

				if (mVelocityTracker != null) {
					mVelocityTracker.recycle();
					mVelocityTracker = null;
				}
				handled = true;
			}
			break;
		}

		return handled;
	}
}
